<?php
/*
 * (C) Copyright 2013 Torsten Gorath (http://www.blauesdach.de/).
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Contributors:
 *     Torsten Gorath
 */
require_once $basedir . "/inc/database.php";

class Role {
    
    private $id = 0;
    private $name = "";
    private $description = "";
    
    protected $permissions;

    /**
     * contructor
     * 
     * @param {int} [$id] id of the role
     * @param {String} [$name] name of the role
     */
    public function __construct($id='', $name='') {
        $this->permissions = array();
        if($id=='' && $name!='') {
            global $VEREIN;
            $query = "SELECT * FROM " . $VEREIN['prefix'] . "roles WHERE name=?";
            $role = Database::getDefault()->executePrepare($query, array($value=>"s"), Role);
            $id = $role->getId();
        }
        if($id!='') {
            $temp = Database::getDefault()->openId("roles",$id, "Role");
            foreach($temp as $key => $value) {
                $this->$key = $value;
            }
        }
        if($this->id != '') {
            $this->initRolePerms();
        }
    }
    
    /**
     * get the current instance as json object
     * 
     * @return {String} Instance data as json object
     */
    public function getJsonData() {
        $var = get_object_vars($this);
        foreach($var as &$value) {
            if(is_object($value) && method_exists($value, 'getJsonData')) {
                $value = $value->getJsonData();
            } else if(is_array($value)) {
                $new_value = array();
                foreach($value as $key=>$val) {
                    $new_value[utf8_encode($key)] = utf8_encode($val);
                }
                $value = $new_value;
            } else {
                $value = utf8_encode($value);
            }
        }
        return $var;
    }
    
    public function getId() {
        return $this->id;
    }
    
    public function getName() {
        return $this->name;
    }
    
    public function getDescription() {
        return $this->description;
    }
    
    public function setDescription($value) {
        $this->description = $value;
    }
    
    public function getPermissions() {
        return $this->permissions;
    }
    
    public function save() {
        $values = array(
            'id' => $this->id,
            'name' => $this->name,
            'description' => $this->description
        );
        if($this->id=="") {
            $this->id = Database::getDefault()->insert("roles",$values);
        } else {
            return Database::getDefault()->update("roles",$values,$this->id);
        }
        return $this->id != 0;
    }
    
    private function initRolePerms() {
        global $VEREIN;
        $query = "SELECT t2.name FROM " . $VEREIN['prefix'] . "role_perm AS t1";
        $query .= " JOIN " . $VEREIN['prefix'] . "permissions AS t2 ON t1.perm_id=t2.id";
        $query .= " WHERE t1.role_id='" . $this->getId() . "'";
        $roles = Database::getDefault()->execute($query);
        for($i = 0; $i<count($roles); $i++) {
            $this->permissions[$roles[$i]['name']] = true;
        }
    }
    
    /**
     * get a role with permissings
     * 
     * @param {String} $role_id id of the role
     * @return {Role} current role object
     */
    public static function getRolePerms($role_id) {
        return new Role($role_id);
    }
    
    /**
     * check if the role has a permission
     * 
     * @param {String} $permission name of the permission
     * @return {boolean} true if set
     */
    public function hasPerm($permission) {
        return isset($this->permissions[$permission]);
    }
    
    /**
     * add the given permission to the role
     * 
     * @param {int} $permision_id permission_id
     * @return {boolean} true if all save
     */
    public function addPerm($permission_id) {
        $permission = new Permission($permission_id);
        if($this->hasPerm($permission->getName())) {
            return true;
        }
        if(Database::getDefault()->insert("role_perm", 
            array('role_id'=>$this->getId(), 'perm_id'=>$permission_id)) != 0) {
            return true;
        };
        return false;
    }
    
    /**
     * insert the given role to the database and return the role id
     * 
     * @param {String} $role_name name of the new role
     * @return {int} new id for the role
     */
    public static function insertRole($role_name) {
        return Database::getDefault()->insert("roles", array('name'=>$role_name));
    }
    
    public static function insertUserRoles($user_id, $roles) {
        foreach($roles as $role_id) {
            Database::getDefault()->insert('user_role', array('user_id'=>$user_id, 'roles_id'=>$role_id));
        }
    }
    
    public static function deleteRoles($roles) {
        global $VEREIN;
        $query = "DELETE t1, t2, t3 FROM " . $VEREIN['prefix'] . "roles AS t1";
        $query .= " JOIN " . $VEREIN['prefix'] . "user_role AS t2 ON t1.id=t2.role_id";
        $query .= " JOIN " . $VEREIN['prefix'] . "role_perm AS t3 ON t1.in=t3.role_id";
        $query .= " WHERE t1.id = :role_id";
        foreach($roles as $role_id) {
            $assoc = array(":role_id"=>$role_id);
            Database::getDefault()->executePrepare($query, $assoc);
        }
        return true;
    }
    
    public static function deleteUserRoles($email) {
        global $VEREIN;
        $query = "DELETE FROM ".$VEREIN['prefix']."user_role WHERE user_id = :user_id";
        $assoc = array('user_id'=>$email);
        return Database::getDefault()->executePrepare($query, $assoc);
    }
    
    /**
     * get all roles
     * 
     * @return {array} Array von Assosiativen Array mit id, name, description
     */
    public static function getAll() {
        global $VEREIN;
        $query = "SELECT * FROM " . $VEREIN['prefix'] . "roles";
        return Database::getDefault()->execute($query, "Role");
    }
}
?>